package com.sengmitnick.timelogger;

import com.zzrv5.mylibrary.ZZRCallBack;
import com.zzrv5.mylibrary.ZZRHttp;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.aafwk.content.Operation;
import ohos.ace.ability.AceAbility;
import ohos.app.AbilityContext;
import ohos.app.Context;
import ohos.bundle.ElementName;
import ohos.data.DatabaseHelper;
import ohos.data.preferences.Preferences;
import ohos.event.intentagent.IntentAgent;
import ohos.event.intentagent.IntentAgentConstant;
import ohos.event.intentagent.IntentAgentHelper;
import ohos.event.intentagent.IntentAgentInfo;
import ohos.event.notification.NotificationHelper;
import ohos.event.notification.NotificationRequest;
import ohos.event.notification.NotificationSlot;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.rpc.RemoteException;
import ohos.utils.zson.ZSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Service {
    private static InternalService instance;

    public static String getAuthorization() {
        return instance.getAuthorization();
    }

    public static void setAuthorization(String Authorization) {
        instance.setAuthorization(Authorization);
    }

    public static void plus(String data) {
        instance.plus(data);
    }

    /**
     * Internal ability registration.
     *
     * @param abilityContext context
     */
    public static void register(AceAbility abilityContext) {
        instance = new InternalService(abilityContext);
    }

    /**
     * Internal ability deregistration.
     *
     * @param ability The AceAbility Object of Invocation
     */
    public static void deRegister(AceAbility ability) {
        instance.onDeRegister(ability);
    }

    public abstract static class TokenCallBack {
        TokenCallBack(){}
        public abstract void onResponse(String Authorization);
    }

    private static class InternalService {
        private static final String BASEURL = "http://101.32.223.115:3002/api";
        private final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MY_TAG");

        private AbilityContext mContext;
        private Preferences preferences;
        private int notificationId;

        public InternalService(AceAbility abilityContext) {
            this.mContext = abilityContext;
            defineNotificationSlot();
        }

        private Preferences getPreferences() {
            if (preferences == null) {
                DatabaseHelper databaseHelper = new DatabaseHelper(mContext.getApplicationContext());
                preferences = databaseHelper.getPreferences(Const.APP_PREFERENCE_NAME);
            }
            return preferences;
        }


        public String getAuthorization() {
            Preferences preferences = getPreferences();
            String Authorization = preferences.getString("Authorization", "");
            System.out.println("getAuthorization: "+ Authorization);
            return Authorization;
        }

        public void setAuthorization(String Authorization) {
            System.out.println("setAuthorization: "+ Authorization);
            Preferences preferences = getPreferences();
            preferences.putString("Authorization", Authorization);
            preferences.flushSync();
        }

        private void updateToken(String Authorization,TokenCallBack callBack) {
            Map<String,String> paramsMap = new HashMap<>();
            Map<String,String> headerMap = new HashMap<>();
            headerMap.put("Content-Type", "application/json");
            headerMap.put("Authorization", Authorization);
            ZZRHttp.post(BASEURL+"/updateToken", paramsMap, headerMap,new ZZRCallBack.CallBackString() {
                @Override
                public void onFailure(int code, String errorMessage) {
                    HiLog.error(LABEL, "updateToken failed. code: " + code + ";errorMessage: " + errorMessage);
                }
                @Override
                public void onResponse(String response) {
                    HiLog.info(LABEL, "updateToken: " +response);
                    ZSONObject data = ZSONObject.stringToZSON(response).getZSONObject("data");
                    if (data != null) {
                        String Authorization = data.getString("accessToken");
                        setAuthorization("{\"authorization\":\""+Authorization+"\"}");
                        callBack.onResponse(Authorization);
                    }
                }
            });
        }

        private void getToken(TokenCallBack callBack) {
            String Authorization = getAuthorization();
            if (Authorization.length() > 0) {
                String finalAuthorization = ZSONObject.stringToZSON(Authorization).getString("authorization");
                System.out.println("getAuthorization: "+ finalAuthorization);
                Map<String,String> paramsMap = new HashMap<>();
                Map<String,String> headerMap = new HashMap<>();
                headerMap.put("Authorization", finalAuthorization);
                ZZRHttp.get(BASEURL+ "/currentUser",paramsMap,headerMap, new ZZRCallBack.CallBackString() {
                    @Override
                    public void onFailure(int code, String errorMessage) {
                        HiLog.error(LABEL, "currentUser failed. code: " + code + ";errorMessage: " + errorMessage);
                        updateToken(finalAuthorization, callBack);
                    }
                    @Override
                    public void onResponse(String response) {
                        HiLog.info(LABEL, "currentUser: " + response);
                        Object data = ZSONObject.stringToZSON(response).getZSONObject("data");
                        if (data == null) {
                            updateToken(finalAuthorization, callBack);
                            return;
                        }
                        callBack.onResponse(finalAuthorization);
                    }
                });
            } else {
                HiLog.info(LABEL, "通知用户登录");
            }
        }

        private NotificationRequest.NotificationContent createNotificationContent(String title, String text) {
            NotificationRequest.NotificationNormalContent content
                    = new NotificationRequest.NotificationNormalContent().setTitle(title).setText(text);
            return new NotificationRequest.NotificationContent(content);
        }

        private void defineNotificationSlot() {
            NotificationSlot notificationSlot = new NotificationSlot(Const.SLOT_ID, Const.SLOT_NAME, NotificationSlot.LEVEL_HIGH);
            notificationSlot.setEnableVibration(true);
            notificationSlot.setLockscreenVisibleness(NotificationRequest.VISIBLENESS_TYPE_PUBLIC);
            try {
                NotificationHelper.addNotificationSlot(notificationSlot);
            } catch (RemoteException ex) {
                HiLog.error(LABEL, "%{public}s", "defineNotificationSlot remoteException.");
            }
        }

        private void publishNotification(String name) {
            HiLog.info(LABEL, "publishNotification: "+name);
            notificationId = 0x1000001;
            NotificationRequest request = new NotificationRequest(notificationId).setSlotId(Const.SLOT_ID)
                    .setTapDismissed(true);
            request.setContent(createNotificationContent("任务开始", name));
            try {
                NotificationHelper.publishNotification(request);
            } catch (RemoteException ex) {
                HiLog.error(LABEL, "Exception occurred during publishNotification invocation.");
            }
        }

        private void cancelNotification() {
            if ("0".equals(String.valueOf(notificationId)) || "null".equals(String.valueOf(notificationId))) return;
            try {
                NotificationHelper.cancelNotification(notificationId);
            } catch (RemoteException ex) {
                HiLog.error(LABEL, "%{public}s", "cancel remoteException.");
            }
        }

        public void plus(String data) {
            cancelNotification();
            getToken(new TokenCallBack() {
                @Override
                public void onResponse(String Authorization) {
                    Map<String,String> headerMap = new HashMap<>();
                    headerMap.put("Content-Type", "application/json");
                    headerMap.put("Authorization", Authorization);
                    ZZRHttp.postJson(BASEURL+ "/event-log", data,headerMap, new ZZRCallBack.CallBackString() {
                        @Override
                        public void onFailure(int code, String errorMessage) {
                            HiLog.error(LABEL, "event-log failed. code: " + code + ";errorMessage: " + errorMessage);
                        }
                        @Override
                        public void onResponse(String response) {
                            HiLog.info(LABEL, "event-log: "+response);
                            String name = ZSONObject.stringToZSON(data).getString("name");
                            if (name != null) {
                                publishNotification(name);
                            }
                        }
                    });
                }
            });
        }

        private void onDeRegister(AceAbility ability) {
            mContext = null;
        }
    }

}
